/*!
 Temelia - Iterators interface; linked list iterator and doubly linked list iterator.

 Copyright (C) 2008 Ceata (http://cod.ceata.org/proiecte/temelia).

 @author Dascalu Laurentiu

 This program is free software; you can redistribute it and
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 3
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#ifndef ITERATOR_H_
#define ITERATOR_H_

#include "platform.h"

struct _linked_list_iterator_t;
struct _doubly_linked_list_iterator_t;

typedef struct _linked_list_iterator_t *linked_list_iterator_t;
typedef struct _doubly_linked_list_iterator_t *doubly_linked_list_iterator_t;

/*!
 * @brief Returns an iterator having default key and default next pointer.
 * Complexity O(1)
 *
 * @param Key
 * @param Next
 */
DECLSPEC linked_list_iterator_t linked_list_iterator_new(void *default_key,
		linked_list_iterator_t default_next);

/*!
 * @brief Frees the memory occuppied by iterator.
 * Complexity O(1)
 *
 * @param Iterator
 */
DECLSPEC void linked_list_iterator_delete(linked_list_iterator_t it);

/*!
 * @brief Returns the key from iterator.
 * Complexity O(1)
 *
 * @param Iterator
 */
DECLSPEC void *linked_list_iterator_get_key(linked_list_iterator_t it);

/*!
 * @brief Returns the next iterator pointer.
 * Complexity O(1)
 *
 * @param Iterator
 */
DECLSPEC linked_list_iterator_t linked_list_iterator_get_next(
		linked_list_iterator_t it);

/*!
 * @brief Sets the key from iterator.
 * Complexity O(1)
 *
 * @param Iterator
 * @param New key
 */
DECLSPEC void linked_list_iterator_set_key(linked_list_iterator_t it, void *new_key);

/*!
 * @brief Sets the next iterator pointer.
 * Complexity O(1)
 *
 * @param Iterator
 * @param New next pointer
 */
DECLSPEC void linked_list_iterator_set_next(linked_list_iterator_t it,
		linked_list_iterator_t new_next);

/*!
 * @brief Joins three iterators : left -> middle -> right; the
 * function do: left->next = middle; middle->next = right; each
 * instruction is executed only if the left statement iterator
 * is not NULL.
 * Complexity O(1)
 *
 * @param Left iterator
 * @param Middle iterator
 * @param Right iterator
 */
DECLSPEC void linked_list_iterator_join(linked_list_iterator_t left,
		linked_list_iterator_t middle, linked_list_iterator_t right);

/*!
 * @brief Splits the link from three iterators:
 * left -> middle -> right => left, middle, right.
 * @see linked_list_iterator_join for addional informations
 * about those iterators.
 * Complexity O(1)
 *
 * @param Left iterator
 * @param Middle iterator
 * @param Right iterator
 */
DECLSPEC void linked_list_iterator_split(linked_list_iterator_t left,
		linked_list_iterator_t middle, linked_list_iterator_t right);

/*!
 * @brief Returns an iterator with default key and prev, next iterators.
 * Complexity O(1)
 *
 * @param Key
 * @param Previous iterator
 * @param Next iterator
 */
DECLSPEC doubly_linked_list_iterator_t doubly_linked_list_iterator_new(void *key,
		doubly_linked_list_iterator_t default_prev,
		doubly_linked_list_iterator_t default_next);

/*!
 * @brief Frees the memory occuppied by iterator.
 * Complexity O(1)
 *
 * @param Iterator
 */
DECLSPEC void doubly_linked_list_iterator_delete(doubly_linked_list_iterator_t it);

/*!
 * @brief Returns the key from iterator.
 * Complexity O(1)
 *
 * @param Iterator
 */
DECLSPEC void *doubly_linked_list_iterator_get_key(doubly_linked_list_iterator_t it);

/*!
 * @brief Returns the previous iterator pointer.
 * Complexity O(1)
 *
 * @param Iterator
 */
DECLSPEC doubly_linked_list_iterator_t doubly_linked_list_iterator_get_prev(
		doubly_linked_list_iterator_t it);

/*!
 * @brief Returns the next iterator pointer.
 * Complexity O(1)
 *
 * @param Iterator
 */
DECLSPEC doubly_linked_list_iterator_t doubly_linked_list_iterator_get_next(
		doubly_linked_list_iterator_t it);

/*!
 * @brief Sets the key from iterator.
 * Complexity O(1)
 *
 * @param Iterator
 * @param Key
 */
DECLSPEC void doubly_linked_list_iterator_set_key(doubly_linked_list_iterator_t it,
		void *key);

/*!
 * @brief Sets the previous iterator pointer.
 * Complexity O(1)
 *
 * @param Iterator
 * @param Previous iterator
 */
DECLSPEC void doubly_linked_list_iterator_set_prev(doubly_linked_list_iterator_t it,
		doubly_linked_list_iterator_t prev);

/*!
 * @brief Sets the next iterator pointer.
 * Complexity O(1)
 *
 * @param Iterator
 * @param Next iterator
 */
DECLSPEC void doubly_linked_list_iterator_set_next(doubly_linked_list_iterator_t it,
		doubly_linked_list_iterator_t next);

/*!
 * @brief Joins three iterators:
 *  left, middle, right => left <-> middle <-> right;
 * each iterator can be NULL.
 * Complexity O(1)
 *
 * @param Left iterator
 * @param Middle iterator
 * @param Right iterator
 */
DECLSPEC void doubly_linked_list_iterator_join(doubly_linked_list_iterator_t left,
		doubly_linked_list_iterator_t middle,
		doubly_linked_list_iterator_t right);

/*!
 * @brief Splits three iterator:
 *  left <-> middle <-> right => left, middle, right;
 *  each iterator can be NULL.
 * Complexity O(1)
 *
 * @param Left iterator
 * @param Middle iterator
 * @param Right iterator
 */
DECLSPEC void doubly_linked_list_iterator_spit(doubly_linked_list_iterator_t left,
		doubly_linked_list_iterator_t middle,
		doubly_linked_list_iterator_t right);

#endif /* ITERATOR_H_ */
